#include <exception>

#include "RelationshipClauseTable.h"


RelationshipClauseTable::RelationshipClauseTable(void) {
}


RelationshipClauseTable::~RelationshipClauseTable(void) {
}

bool RelationshipClauseTable::addRelationshipEntry(RelationshipType relationshipType, 
	std::string relationshipArg1, RelationshipArgumentType relationshipArgType1,
	std::string relationshipArg2, RelationshipArgumentType relationshipArgType2) {
		// Error checking
		if (relationshipType == NULL) {
			return false;
		}
		if (relationshipArg1 == "" || relationshipArg2 == "") {
			return false;
		}
		if (relationshipArgType1 == NULL || relationshipArgType2 == NULL) {
			return false;
		}

		RelationshipEntry entry;
		entry.relationshipType = relationshipType;
		entry.relationshipArguments[0] = relationshipArg1;
		entry.relationshipArguments[1] = relationshipArg2;
		entry.relationshipArgumentTypes[0] = relationshipArgType1;
		entry.relationshipArgumentTypes[1] = relationshipArgType2;
		entry.numberOfArguments = 2;

		if (mRelationshipEntryMap.find(entry) == mRelationshipEntryMap.end()) {
			mRelationshipEntries.push_back(entry);
			mRelationshipEntryMap.insert(std::pair<RelationshipEntry, int> (entry, 1));
			return true;
		} else return false;
		
}

bool  RelationshipClauseTable::existRelationshipEntry(RelationshipType relationshipType, 
	std::string relationshipArg1, RelationshipArgumentType relationshipArgType1,
	std::string relationshipArg2, RelationshipArgumentType relationshipArgType2) {
				// Error checking
		if (relationshipType == NULL) {
			return false;
		}
		if (relationshipArg1 == "" || relationshipArg2 == "") {
			return false;
		}
		if (relationshipArgType1 == NULL || relationshipArgType2 == NULL) {
			return false;
		}

		RelationshipEntry entry;
		entry.relationshipType = relationshipType;
		entry.relationshipArguments[0] = relationshipArg1;
		entry.relationshipArguments[1] = relationshipArg2;
		entry.relationshipArgumentTypes[0] = relationshipArgType1;
		entry.relationshipArgumentTypes[1] = relationshipArgType2;
		entry.numberOfArguments = 2;

		return (mRelationshipEntryMap.find(entry)!=mRelationshipEntryMap.end());
/*
		for (std::vector<RelationshipEntry>::iterator it = mRelationshipEntries.begin() ; it != mRelationshipEntries.end(); ++it)
			if (*it == entry) return true;
		return false;
*/
}

RelationshipEntry RelationshipClauseTable::getRelationshipEntry(int index) {
	if (index < 0 || index >= getNumberOfEntries()) {
		RelationshipEntry entry;
		return entry;
	}
	return mRelationshipEntries.at(index);
}

int RelationshipClauseTable::getNumberOfEntries() {
	return mRelationshipEntries.size();
}

bool RelationshipClauseTable::removeRedundancy() {
	//for (std::vector<RelationshipEntry>::iterator it = mRelationshipEntries.begin() ; it != mRelationshipEntries.end(); ++it)
	return true;
}

bool RelationshipClauseTable::replaceSynonym(std::string s1, std::string s2) {
	if (s1.compare(s2) ==0) return true;

	std::unordered_map<RelationshipEntry,int>::iterator it;
	RelationshipEntry e;
	bool modified = true;
	bool o_modified = false;
	for (int i=0; i<mRelationshipEntries.size(); i++) {
		e = mRelationshipEntries.at(i);
		modified = false;
		for (int j = 0; j<e.numberOfArguments ; j++) {
			if (e.relationshipArguments[j].compare(s2) ==0 && e.relationshipArgumentTypes[j]!=STRING) {
				e.relationshipArguments[j] = s1;
				modified = true;
			}
		}
		if (modified) {
			mRelationshipEntryMap.erase(mRelationshipEntries.at(i));
			mRelationshipEntryMap.insert(std::pair<RelationshipEntry,int> (e, 1));
		}
		o_modified = (modified)?true:o_modified;
	}

	if (o_modified) {
		mRelationshipEntries.clear();
	
		for (it = mRelationshipEntryMap.begin(); it != mRelationshipEntryMap.end(); ++it) {
			mRelationshipEntries.push_back(it->first);
		}
	}
	
	//int size = mRelationshipEntries.size();
	


	/*
	for (std::vector<RelationshipEntry>::iterator it = mRelationshipEntries.begin() ; it != mRelationshipEntries.end(); ++it) {
		bool modified = false;
		for (int i = 0; i<it->numberOfArguments ; i++) {
			if (it->relationshipArguments[i].compare(s2) ==0 && it->relationshipArgumentTypes[i]!=STRING) {
				it->relationshipArguments[i] = s1;
				modified = true;

			}
		}

		if (modified) {
			for (std::vector<RelationshipEntry>::iterator it2 = mRelationshipEntries.begin() ; it2 != mRelationshipEntries.end(); ++it2) {
				if (it!=it2 && *it2 == *it) {
					swap(
				}
			}

		}
	}
	*/
	return true;
}